package com.focus.xyz.union.action;

import com.focus.xyz.core.utils.Constants;
import com.focus.xyz.core.utils.ExcelUtils;
import com.focus.xyz.core.utils.prop.ConfigPropInfo;
import org.apache.commons.lang.StringUtils;
import org.openqa.selenium.os.WindowsUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
import org.testng.SkipException;
import org.testng.annotations.*;

import java.lang.reflect.Method;
import java.util.List;

/**
 * Created by chenmeng on 2016/4/29.
 */
public class KeyWordSuit {

    private static transient Logger logger = LoggerFactory.getLogger(KeyWordSuit.class);
    private static ExcelUtils eu;
    private static Method[] methods = null;
    private boolean caseStatus;
    private boolean isFound;
    private String oper;
    private String element;
    private String param;
    private String stepRow;
    private String browser;
    private String nodeUrl;

    @BeforeClass
    public void beforeClass() throws Exception {
         eu = new ExcelUtils(ConfigPropInfo.TEST_DATA_DIR + ConfigPropInfo.TEST_KEYWORD_FILE);
        //清除 excel中的 结果字段
        setSheet(Constants.STEP_SHEET);
        eu.clearCol(Integer.valueOf(Constants.STEP_RES_COL_IDX));
        setSheet(Constants.CASE_SHEET);
        eu.clearCol(Integer.valueOf(Constants.CASE_RES_COL_IDX));
        methods = KeyWordAction.class.getMethods();
    }

    @Parameters({"browser"})
    @AfterClass
    public void afterClass(String browser){
        closeBrowser(browser);
    }

    @BeforeMethod
    public void setUp(){

    }

    @AfterMethod
    public void tearDown(){

    }

    @DataProvider(name = "data")
    public Object[][] getKeyWordSuit(){
        String[][] data = null;
        try {
            setSheet(Constants.CASE_SHEET);
            data = eu.readExcelArray();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return data;
    }


    @Parameters({"nodeUrl","browser"})
    @Test(description = "设置打开的浏览器类型及驱动类型")
    public void setBrowser(String nodeUrl,String browser) throws Exception{
        this.nodeUrl = nodeUrl;
        this.browser = browser;
    }

    @Test(dataProvider = "data",dependsOnMethods = {"setBrowser"})
    public void testSuitByExcel(String index,String caseID,String desc,String isRun,String result) throws Exception{
        caseStatus = false;
        if(Constants.NOT_RUN.equalsIgnoreCase(isRun)){
            throw new SkipException(String.format("【%s】设置状态为：%s,没有执行",caseID,isRun));
        }
        if(StringUtils.isNotBlank(caseID)){
            OUT:for(String[] steps : getStepsByCase(caseID)){
                isFound = false;
                oper = steps[0];
                element = steps[1];
                param = steps[2];
                stepRow = steps[3];
                for(Method m : methods){
                    if(StringUtils.isNotBlank(oper)&&oper.equals(m.getName())){
                        m.setAccessible(true);//test
                        //只要元素为空，直接反射调用
                        if(StringUtils.isBlank(element)){
                            Object[] paras = null;
                            //打开浏览器，参数来自testng主配置文件
                            if("OpenBrowser".equals(oper)){
                                paras = new String[]{nodeUrl,browser};
                            }
                            if(StringUtils.isNotBlank(param)){
                                String[] tt = param.split(Constants.SPLIT_DOT);
                                paras = new Object[tt.length];
                                for(int i = 0;i<tt.length;i++){
                                    if(Constants.NULL.equals(tt[i])){
                                        paras[i] = null;
                                    }else{
                                        paras[i] = tt[i];
                                    }
                                }
                            }
                            try {
                                m.invoke(KeyWordAction.class.newInstance(),paras);
                                isFound = true;
                                caseStatus = true;
                                logger.info("【" + oper + " 执行成功。】");
                                setStatus(Constants.STEP_SHEET,Constants.M_SUC,stepRow,Constants.STEP_RES_COL_IDX);
                                break;
                            } catch (Exception e) {
                                caseStatus = false;
                                logger.info("【" + oper + " 执行失败。】" + e);
                                setStatus(Constants.STEP_SHEET,Constants.M_FAIL,stepRow,Constants.STEP_RES_COL_IDX);
                                setStatus(Constants.CASE_SHEET,Constants.M_FAIL,index,Constants.CASE_RES_COL_IDX);
                                //测试步骤执行失败需要关闭浏览器进程
                                closeBrowser(browser);
                                Assert.fail(String.format("【测试用例：%s的操作：%s执行失败。】",caseID,oper),e);
                                break OUT;
                            }
                        }else{
                            //元素不为空,根据元素表达式执行相应操作
                        }
                    }else{
                        continue;
                    }
                }
                if(!isFound){
                    logger.info("【" + oper + " 未在KeyWordAction中定义。】");
                    break;
                }
            }
        }else{
            throw new SkipException("用例列表中没有定义用例ID,用例没有运行");
        }
        if(caseStatus){
            //用例运行成功
            setSheet(Constants.CASE_SHEET);
            setStatus(Constants.CASE_SHEET,Constants.M_SUC,index,Constants.CASE_RES_COL_IDX);
        }
    }

    public List<String[]> getStepsByCase(String tc){
        setSheet(Constants.STEP_SHEET);
        List<String[]> list = eu.getCells(tc,Constants.STEP_IDX);
        return list;
    }

    public void setSheet(String sheetName){
        eu.setSelectedSheetName(sheetName);
        eu.setOnlyReadOneSheet(true);
        eu.setStartReadPos(1);
    }

    public void setStatus(String sheetName,String status,String rowNum,String colNum){
        setSheet(sheetName);
        eu.setCell(status,Integer.valueOf(rowNum),Integer.valueOf(colNum));
    }

    public void closeBrowser(String browser){
        if(Constants.IE.equals(browser)){
            WindowsUtils.tryToKillByName("iexplore.exe");
        }else if(Constants.CHROME.equals(browser)){
            WindowsUtils.tryToKillByName("chrome.exe");
        }else if(Constants.FIREFOX.equals(browser)){
            WindowsUtils.tryToKillByName("firefox.exe");
        }
    }

    public void doTask() throws Exception{

    }

}
